home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 1.iso
/
toolbox
/
src
/
exampleCode
/
opengl
/
xlib
/
toverlay.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-11-11
|
12KB
|
484 lines
/*
* (c) Copyright 1994, Silicon Graphics, Inc.
* ALL RIGHTS RESERVED
*
* Permission to use, copy, modify, and distribute this software for
* any purpose and without fee is hereby granted, provided that the above
* copyright notice appear in all copies and that both the copyright notice
* and this permission notice appear in supporting documentation, and that
* the name of Silicon Graphics, Inc. not be used in advertising
* or publicity pertaining to distribution of the software without specific,
* written prior permission.
*
* THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
* AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
* GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
* SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
* KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
* LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
* THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
* POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
*
* U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND
* Use, duplication, or disclosure by the Government is subject to
* restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
* (c)(1)(ii) of the Rights in Technical Data and Computer Software
* clause at DFARS 252.227-7013 and/or in similar or successor
* clauses in the FAR or the DOD or NASA FAR Supplement.
* Unpublished-- rights reserved under the copyright laws of the
* United States. Contractor/manufacturer is Silicon Graphics,
* Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
*
* OpenGL(TM) is a trademark of Silicon Graphics, Inc.
*/
/*
** % cc -o toverlay toverlay.c -lGL
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#define DISPLAY_BOTH 0
#define DISPLAY_NORMAL 1
#define DISPLAY_OVERLAY 2
static void
drawSquare(float c)
{
glIndexf(c);
glBegin(GL_QUADS);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(1.0, 0.0, 0.0);
glVertex3f(1.0, 1.0, 0.0);
glVertex3f(0.0, 1.0, 0.0);
glEnd();
}
static void
drawCheck(float c1, float c2)
{
int w = 4, h = 4;
int i, j;
for (j=0; j<h; ++j) {
for (i=0; i<w; ++i) {
glPushMatrix();
glTranslatef((1.0/w) * i, (1.0/h) * j, 0.0);
glScalef(1.0/w, 1.0/h, 1.0);
if ((i & 1) ^ (j & 1)) {
drawSquare(c1);
} else {
drawSquare(c2);
}
glPopMatrix();
}
}
}
static void
usage(int argc, char **argv)
{
fprintf(stderr, "\n");
fprintf(stderr, "usage: %s [options]\n", argv[0]);
fprintf(stderr, "\n");
fprintf(stderr, " OpenGL overlay plane rendering test\n");
fprintf(stderr, "\n");
fprintf(stderr, " Options:\n");
fprintf(stderr, " -nm just display normal plane window\n");
fprintf(stderr, " -ov just display overlay plane window\n");
fprintf(stderr, " -m mode display both windows according to mode:\n");
fprintf(stderr, " 0 overlay is child of normal (default)\n");
fprintf(stderr, " 1 both are children of root\n");
fprintf(stderr, " 2 both are children of a child of root\n");
fprintf(stderr, " -bindov bind opengl to overlay window first\n");
fprintf(stderr, " -gl toggle opengl rendering\n");
fprintf(stderr, " -a toggle animation\n");
fprintf(stderr, "\n");
}
static Colormap
buildColormap(Display *dpy, Window win, XVisualInfo *xvis)
{
Colormap cmap;
if ((cmap = XCreateColormap(dpy, win, xvis->visual, AllocNone)) == None) {
fprintf(stderr, "can't create colormap\n");
exit(EXIT_FAILURE);
}
if (xvis->class == PseudoColor) {
int mapSize = 1 << xvis->depth;
int firstEntry = 0;
int entry;
unsigned long *pixels;
pixels = (unsigned long *) calloc(mapSize, sizeof(unsigned long));
if (!XAllocColorCells(dpy, cmap, True, NULL, 0, pixels, mapSize))
{
if (!XAllocColorCells(dpy, cmap, True, NULL, 0, pixels, mapSize-1))
{
fprintf(stderr, "can't alloc enough colormap entries\n");
exit(EXIT_FAILURE);
}
firstEntry = 1;
}
for (entry=firstEntry; entry<mapSize; ++entry) {
XColor xcol;
int hue = entry % 8;
short val = 0xffff;
xcol.pixel = entry;
xcol.red = (hue==1 || hue==5 || hue==6 || hue==7) ? val : 0;
xcol.green = (hue==2 || hue==4 || hue==6 || hue==7) ? val : 0;
xcol.blue = (hue==3 || hue==4 || hue==5 || hue==7) ? val : 0;
xcol.flags = DoRed | DoGreen | DoBlue;
XStoreColor(dpy, cmap, &xcol);
}
free((void *) pixels);
}
return cmap;
}
static void
windopen(Display **dpy_ret, Window *win_ret,
GLXContext *ctx_ret, int *visAttrs,
const char *name, int w, int h)
{
static Display *dpy = NULL;
int scr;
Window root;
XVisualInfo *xvis;
GLXContext ctx;
XSetWindowAttributes xswa;
Colormap cmap;
Window win;
XEvent event;
if (dpy == NULL) {
if ((dpy = XOpenDisplay(NULL)) == NULL) {
fprintf(stderr, "can't open display\n");
exit(EXIT_FAILURE);
}
}
scr = DefaultScreen(dpy);
root = RootWindow(dpy, scr);
if ((xvis = glXChooseVisual(dpy, scr, visAttrs)) == NULL) {
fprintf(stderr, "can't find visual\n");
exit(EXIT_FAILURE);
}
if ((ctx = glXCreateContext(dpy, xvis, NULL, True)) == None) {
fprintf(stderr, "can't create context\n");
exit(EXIT_FAILURE);
}
xswa.colormap = buildColormap(dpy, root, xvis);
xswa.background_pixel = 0;
xswa.border_pixel = 0;
xswa.event_mask = KeyPressMask | ExposureMask | StructureNotifyMask;
win = XCreateWindow(dpy, root, 0, 0, w, h, 0,
xvis->depth, InputOutput, xvis->visual,
CWColormap | CWBackPixel | CWBorderPixel | CWEventMask,
&xswa);
if (name) {
XStoreName(dpy, win, name);
}
*dpy_ret = dpy;
*win_ret = win;
*ctx_ret = ctx;
}
static Bool
waitForNotify(Display *dpy, XEvent *event, XPointer arg)
{
return (event->type == MapNotify && event->xmap.window == (Window) arg);
}
static int normalVisAttrs[] = {
GLX_LEVEL, 0,
GLX_BUFFER_SIZE, 4,
None
};
static int overlayVisAttrs[] = {
GLX_LEVEL, 1,
GLX_BUFFER_SIZE, 2,
None
};
int
main(int argc, char **argv)
{
int mode = DISPLAY_BOTH;
int useGL = 1;
int animate = 1;
int manageTogether = 1;
int manageUsingParent = 0;
int delayBind = 0;
int width = 300, height = 300;
int ovWidth = width, ovHeight = height;
float spin0 = 0.0, spinRate0 = 1.0;
float spin1 = 45.0, spinRate1 = -1.0;
int normInit = 0;
int overInit = 0;
Display *dpy;
Window parentWin = None;
GLXContext parentCtx = None;
Window normWin = None;
GLXContext normCtx = None;
Window overWin = None;
GLXContext overCtx = None;
XEvent event;
int i;
for (i=1; i<argc; ++i) {
if (!strcmp("-nm", argv[i]))
{
mode = DISPLAY_NORMAL;
}
else if (!strcmp("-ov", argv[i]))
{
mode = DISPLAY_OVERLAY;
}
else if (!strcmp("-m", argv[i]) && (i+1 < argc))
{
mode = DISPLAY_BOTH;
switch (atoi(argv[++i])) {
case 0:
manageTogether = 1; manageUsingParent = 0;
break;
case 1:
manageTogether = 0; manageUsingParent = 0;
break;
case 2:
manageTogether = 1; manageUsingParent = 1;
break;
default:
usage(argc, argv);
exit(EXIT_FAILURE);
break;
}
}
else if (!strcmp("-bindov", argv[i]))
{
delayBind = 1;
}
else if (!strcmp("-gl", argv[i]))
{
useGL = !useGL;
}
else if (!strcmp("-a", argv[i]))
{
animate = !animate;
}
else
{
usage(argc, argv);
exit(EXIT_FAILURE);
}
}
if (mode == DISPLAY_BOTH && manageUsingParent) {
windopen(&dpy, &parentWin, &parentCtx,
normalVisAttrs, "overlay test", width, height);
XMapWindow(dpy, parentWin);
XIfEvent(dpy, &event, waitForNotify, (XPointer) parentWin);
}
if (mode == DISPLAY_BOTH || mode == DISPLAY_NORMAL) {
windopen(&dpy, &normWin, &normCtx,
normalVisAttrs, "overlay test", width, height);
if (mode == DISPLAY_BOTH && manageUsingParent) {
XReparentWindow(dpy, normWin, parentWin, 0, 0);
}
XMapWindow(dpy, normWin);
XIfEvent(dpy, &event, waitForNotify, (XPointer) normWin);
if (useGL && !delayBind) {
glXMakeCurrent(dpy, normWin, normCtx);
}
}
if (mode == DISPLAY_BOTH || mode == DISPLAY_OVERLAY) {
windopen(&dpy, &overWin, &overCtx,
overlayVisAttrs, "overlay test", ovWidth, ovHeight);
if (mode == DISPLAY_BOTH && manageTogether) {
if (manageUsingParent) {
XReparentWindow(dpy, overWin, parentWin, 0, 0);
} else {
XReparentWindow(dpy, overWin, normWin, 0, 0);
}
}
XMapWindow(dpy, overWin);
XIfEvent(dpy, &event, waitForNotify, (XPointer) overWin);
if (useGL && !delayBind) {
glXMakeCurrent(dpy, overWin, overCtx);
}
}
if (mode == DISPLAY_BOTH && manageTogether) {
Window winList[3];
if (manageUsingParent) {
winList[0] = overWin;
winList[1] = normWin;
winList[2] = parentWin;
XSetWMColormapWindows(dpy, parentWin, winList, 3);
} else {
winList[0] = overWin;
winList[1] = normWin;
XSetWMColormapWindows(dpy, normWin, winList, 2);
}
}
while (1) {
int reconfigure = 0;
int redraw = 0;
if (XPending(dpy)) {
KeySym ks;
XNextEvent(dpy, &event);
switch (event.type) {
case KeyPress:
XLookupString(&event.xkey, NULL, 0, &ks, NULL);
if (ks == XK_Escape) {
exit(EXIT_SUCCESS);
}
break;
case Expose:
redraw = 1;
break;
case ConfigureNotify:
if (mode == DISPLAY_BOTH && manageTogether) {
if (manageUsingParent &&
event.xconfigure.window == parentWin)
{
width = ovWidth = event.xconfigure.width;
height = ovHeight = event.xconfigure.height;
XResizeWindow(dpy, normWin, width, height);
XResizeWindow(dpy, overWin, ovWidth, ovHeight);
}
if (!manageUsingParent &&
event.xconfigure.window == normWin)
{
width = ovWidth = event.xconfigure.width;
height = ovHeight = event.xconfigure.height;
XResizeWindow(dpy, overWin, ovWidth, ovHeight);
}
} else {
if (event.xconfigure.window == normWin) {
width = event.xconfigure.width;
height = event.xconfigure.height;
}
if (event.xconfigure.window == overWin) {
ovWidth = event.xconfigure.width;
ovHeight = event.xconfigure.height;
}
}
reconfigure = 1;
redraw = 1;
break;
default:
break;
}
}
if (animate) {
spin0 += spinRate0;
if (spin0 > 360.0) spin0 -= 360.0;
spin1 += spinRate1;
if (spin1 > 360.0) spin1 -= 360.0;
redraw = 1;
}
if (useGL) {
if (mode == DISPLAY_BOTH || mode == DISPLAY_OVERLAY) {
if (mode == DISPLAY_BOTH || !overInit) {
glXMakeCurrent(dpy, overWin, overCtx);
if (!overInit) {
glMatrixMode(GL_PROJECTION);
glOrtho(-1, 1, -1, 1, 1, 3);
glMatrixMode(GL_MODELVIEW);
glTranslatef(0.0, 0.0, -2.0);
glLineWidth(4.0);
overInit = 1;
}
}
if (reconfigure) {
glViewport(0, 0, ovWidth, ovHeight);
}
if (redraw) {
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glRotatef(spin1, 0, 0, 1);
glScalef(1.25, 1.25, 1.0);
glTranslatef(-0.5, -0.5, 0.0);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
drawCheck(1, 2);
glPopMatrix();
}
}
if (mode == DISPLAY_BOTH || mode == DISPLAY_NORMAL) {
if (mode == DISPLAY_BOTH || !normInit) {
glXMakeCurrent(dpy, normWin, normCtx);
if (!normInit) {
glMatrixMode(GL_PROJECTION);
glOrtho(-1, 1, -1, 1, 1, 3);
glMatrixMode(GL_MODELVIEW);
glTranslatef(0.0, 0.0, -2.0);
normInit = 1;
}
}
if (reconfigure) {
glViewport(0, 0, width, height);
}
if (redraw) {
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glRotatef(spin0, 0, 0, 1);
glScalef(1.25, 1.25, 1.0);
glTranslatef(-0.5, -0.5, 0.0);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
drawCheck(3, 4);
glPopMatrix();
}
}
}
}
}